/**
 *  @type Common flyComponent
 *  @role 衣有道 fly-Input
 *  @createDate Mr.Liu on 2017.06.16.17:52
 */

import React,{PropTypes} from "react";
import classnames from 'classnames';
import {type} from '../../util/type';
import {omit} from '../../util/omit';

import TextAuotoSize from './TextAutoSzie'

function fixControlledValue(value) {
    if (typeof value === 'undefined' || value === null) {
        return '';
    }
    return value;
}

export default class Input extends React.Component {

    static defaultProps = {
        disabled: false,
        prefixCls: 'fly-input',
        type: 'text',
    };

    static propTypes = {
        type: PropTypes.string,
        id: PropTypes.oneOfType([
            PropTypes.string,
            PropTypes.number,
        ]),
        size: PropTypes.oneOf(['small', 'default', 'big']),
        status:PropTypes.oneOf(["error","done"]),
        errorInfo:PropTypes.string,
        disabled: PropTypes.bool,
        value: PropTypes.any,
        defaultValue: PropTypes.any,
        className: PropTypes.string,
        onChange:PropTypes.func,
        onPressEnter: PropTypes.func,
        onKeyDown: PropTypes.func,

        // addonBefore: PropTypes.React.ReactNode,
        // addonAfter: PropTypes.React.ReactNode,
        prefixCls: PropTypes.string,
        autosize: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
    };

    state = {
        TextAreaStyle:null
    };

    FrameId = "";

    componentDidMount(){
        this.resizeTextInput();
    }

    nextFrameAction(cb){
        if(window.requestAnimationFrame) {
           this.FrameId = window.requestAnimationFrame(cb);
        }
        this.FrameId = window.setTimeout(cb,1);
    }

    clearNextFrameAction(nextFramId){
        if(nextFramId){
            if(window.cancelAnimationFrame){
                window.cancelAnimationFrame(nextFramId);
            }
            window.clearTimeout(nextFramId);
        }
    }

    componentWillReceiveProps(nextProps){
        // 更新status
        if(this.props.value !== nextProps.value){
            this.nextFrameAction(this.resizeTextInput);
        }
        this.clearNextFrameAction(this.FrameId)
    };

    handleKeyDown = (e)=>{
        const {onPressEnter,onKeyDown} = this.props;

        if(e.keyCode === 13 && onPressEnter){
            onPressEnter();
        }

        if(onKeyDown){ onKeyDown(); }
    };

    resizeTextInput = ()=>{
        const {type,autosize} = this.props;

        if(type !== "textarea" || !this.refs.input || !autosize){
            return;
        }

        // 类型判断？ 非空转换？
        const minRow = autosize.minRow ? autosize.minRow : null;
        const maxRow = autosize.maxRow ? autosize.maxRow : null;

        const TextAreaStyle = TextAuotoSize(this.refs.input,false,minRow,maxRow);

        this.setState({TextAreaStyle})
    };

    handleTextChange = (e)=>{
        const {value,onChange} = this.props;

        // if(value){
        //     this.resizeTextInput();
        // }

        if(onChange){
            onChange(e);
        }
    };

    // 负责return 两个 input 和它们之间的逻辑
    renderInput(){
        const props = Object.assign({},this.props);

        const otherProps = omit(this.props,[
            'prefixCls',
            "onPressEnter",
            "className"
        ]);

        const prefixCls = props.prefixCls;

        if (!props.type) {
            return props.children;
        }

        const inputClassName = classnames(prefixCls,{
            [`${prefixCls}-sm`] : props.size === 'small',
            [`${prefixCls}-lg`] : props.size === "big",
            [`${prefixCls}-error`] : props.status === "error"
        },props.className);

        // 如果有value的话
        if("value" in props){
            otherProps.value = fixControlledValue(props.value);
            delete otherProps.defaultValue;
        }

        switch(props.type){
            case "textarea":
                return (
                    <textarea
                        className={inputClassName}
                        {...otherProps}
                        style={Object.assign({},props.style,this.state.TextAreaStyle)}
                        onChange={this.handleTextChange}
                        ref="input"
                    />
                );
            default:
                return (
                    <input
                        {...otherProps}
                        className={inputClassName}
                        onKeyDown={this.handleKeyDown}
                        ref="input"
                    />
                )
        }
    }

    render() {return this.renderInput();}
}

export {Input}